import KY3D from "@/editor/KY3D";
import { CurMode } from "@/libs/const/enum";
import { Color, DirectionalLight, DoubleSide, GridHelper, HemisphereLight, LineBasicMaterial, Mesh, MeshBasicMaterial, OrthographicCamera, PerspectiveCamera, PlaneGeometry, Scene, sRGBEncoding, Vector3, WebGLRenderer } from "three";
import { CSS2DRenderer } from "three/examples/jsm/renderers/CSS2DRenderer";
import TrackCameraCtrl from "../ctrl/TrackCameraCtrl";

/**
 * 3D 场景
 */
export default class MainScene {

    /** 场景 */
    private _scene: Scene;
    /** 摄像机:透视 */
    private _pcamera: PerspectiveCamera;
    /** 渲染 */
    private _render: WebGLRenderer;
    /** css2drender */
    private _css2dReder: CSS2DRenderer;
    /** 轨迹球控制器 */
    private _trackCtrl: TrackCameraCtrl;
    /** 当前控制器 */
    private _controls: any;
    /** 当前使用的摄像机 */
    private _camera: any;
    /** 辅助网格 */
    private _grid: GridHelper;
    /** 平面 */
    private _plane:Mesh;
    /** 视口宽 */
    private _viewWidth: number;
    /** 视口高 */
    private _viewHeight: number;

    get plane():Mesh {
        return this._plane;
    }

    set viewWidth(value: number) {
        this._viewWidth = value;
    }

    get viewWidth(): number {
        return this._viewWidth;
    }

    set viewHeight(value: number) {
        this._viewHeight = value;
    }

    get viewHeight(): number {
        return this._viewHeight;
    }

    get camera(): any {
        return this._camera;
    }

    get css2dRender(): CSS2DRenderer {
        return this._css2dReder;
    }

    get controls(): any {
        return this._controls;
    }

    get scene(): Scene {
        return this._scene;
    }

    get render(): WebGLRenderer {
        return this._render;
    }

    constructor() {

        this.initData();
        this.createScene();
        this.createPCamera();
        this.createLight();
        this.addPlane();
        this.addGrid();
        this.createRender();
        this.createCSS2DRender();
        this.createControls();
    }

    private initData():void {
        this._viewWidth = window.innerWidth;
        this._viewHeight = window.innerHeight;
    }

    private createScene(): void {
        this._scene = new Scene();
        this._scene.background = new Color(0x333333);
    }


    private createPCamera(): void {
        this._pcamera = new PerspectiveCamera(60, this._viewWidth / this._viewHeight, 0.01, 1000);
        this._pcamera.position.set(5, 5, 5);
        this._pcamera.lookAt(new Vector3(0, 0, 0));
        this._camera = this._pcamera;
    }

    /** 添加控制器 */
    private createControls(): void {
        this._trackCtrl = new TrackCameraCtrl(this._camera, this._css2dReder.domElement, this._render.domElement);
        this._controls = this._trackCtrl;
    }

    /** 添加光 */
    private createLight(): void {
        // 环境光，全局光照
        const hemiLight = new HemisphereLight(0xffffff, 0x333333, 0.6);
        hemiLight.position.set(0, 200, 0);
        this._scene.add(hemiLight);

        // 添加平行光,用来模拟太阳光
        let dirLight = new DirectionalLight(0xffffff, 0.6);
        dirLight.position.set(0, 100, 100);
        this._scene.add(dirLight);
    }

    private addPlane():void {
        let planeBufferGeomery = new PlaneGeometry(100, 100);
        this._plane = new Mesh(planeBufferGeomery, new MeshBasicMaterial({
            color: 0x333333,
            reflectivity: 0,
            transparent: true,
            opacity: 0.1,
            side: DoubleSide,
        }));
        this._plane.rotation.x = -Math.PI / 2;
        this._plane.position.set(0, 0, 0)
        this._plane.visible = false;
        this._scene.add(this._plane);
    }

    private addGrid(): void {
        this._grid = new GridHelper(100, 100, 0x222222, 0x111111);
        (this._grid.material as LineBasicMaterial).opacity = 0.6;
        (this._grid.material as LineBasicMaterial).transparent = true;
        this._grid.position.set(0, 0, 0);
        this._scene.add(this._grid);
    }

    createCSS2DRender(): void {
        this._css2dReder = new CSS2DRenderer();
        this._css2dReder.setSize(this._viewWidth, this._viewHeight);
        this._css2dReder.domElement.style.position = 'absolute';
        this._css2dReder.domElement.style.top = '0px';
    }

    private createRender(): void {
        this._render = new WebGLRenderer({
            precision: "highp", // 着色器精度:高
            antialias: true, // 锯齿
            alpha: true, // canvas是否包含alpha (透明度)
            logarithmicDepthBuffer: true, //是否使用对数深度缓存
        });
        // 设置尺寸
        this._render.setSize(this._viewWidth, this._viewHeight);
        // 设置设备的物理像素比
        this._render.setPixelRatio(window.devicePixelRatio);
        this._render.outputEncoding = sRGBEncoding;
    }

    onResize(): void {

        if(KY3D.mode === CurMode.SPECT){
            this._viewWidth = window.innerWidth;
            this._viewHeight = window.innerHeight;
        }
        if (this._trackCtrl) {
            this._trackCtrl.screen.width = this._viewWidth;
            this._trackCtrl.screen.height = this._viewHeight;
        }

        
        // 渲染
        this._render.setSize(this._viewWidth, this._viewHeight);
        this._css2dReder.setSize(this._viewWidth, this._viewHeight);
        // 透视相机
        if (this.camera instanceof PerspectiveCamera) {
            this._camera.aspect = this._viewWidth / this._viewHeight;
            this.camera.updateProjectionMatrix();
        }
        // else if (this.camera instanceof OrthographicCamera) {
        //     // 正交相机
        //     let aspect = this._viewWidth / this._viewHeight;
        //     this._camera.left = - this.frustumSize * aspect / 2;
        //     this._camera.right = this.frustumSize * aspect / 2;
        //     this._camera.top = this.frustumSize / 2;
        //     this._camera.bottom = - this.frustumSize / 2;
        //     this._camera.updateProjectionMatrix();
        // }
    }

    onsetview(obj: any): void {

        this._viewWidth = obj.width;
        this._viewHeight = obj.height;
        this.onResize();
    }


}